﻿using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Wechat.Webapi.Modal;
using Wechat.Webapi.Modal;
using Wechat.Webapi.Modal;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;

namespace Wechat.Webapi
{
    public static class HttpClientWeixinHelper
    {
        public const string GetUUidLink = "https://login.weixin.qq.com/jslogin";
        public const string GetErcodeLink = "https://api.pwmqr.com/qrcode/create/?url=https://login.weixin.qq.com/l/";
        public const string checkloginLink = "https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login";
        public const string LoginSuccessLink = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?mod=desktop";
        public const string initLink = "/cgi-bin/mmwebwx-bin/webwxinit";
        public const string autoUrl = "/cgi-bin/mmwebwx-bin/webwxpushloginurl?uin=";
        public const string logoutlink = "/cgi-bin/mmwebwx-bin/webwxlogout";
        public const string UUidRexpattern = "window.QRLogin.code = (\\d+); window.QRLogin.uuid = \"(\\S+?)\";";
        public const string checkloginCode = "window.code=(\\d+)";
        public const string checkloginUrl = "window.redirect_uri=\"(\\S+)\";";

        public static string GetUUID(this Client client)
        {
            Dictionary<string, string> param = new Dictionary<string, string>();
            param["appid"] = "wx782c26e4c19acffb";
            param["fun"] = "new";
            param["redirect_uri"] = OtherUtils.UrlEncode(GetUUidLink + "?mod=desktop");
            string result = client.HttpClientInfo.GetString(GetUUidLink, param);
            Match match = Regex.Match(result, UUidRexpattern);
            if (match.Groups[1].Value == "200")
            {
                return match.Groups[2].Value;
            }
            return "";

        }

        /// <summary>
        /// 获取base64的二维码
        /// </summary>
        /// <param name="client"></param>
        /// <param name="uuid"></param>
        /// <returns></returns>
        public static string GetERcodeBase64(this Client client, string uuid)
        {
           
            return "https://login.weixin.qq.com/l/{uuid}".QRCode();
        }
        /// <summary>
        /// 获取登录二维码图片
        /// </summary>
        /// <param name="client"></param>
        /// <param name="uuid"></param>
        /// <returns></returns>
        public static Image GetERcode(this Client client, string uuid)
        {
            string qrcodeUrl = string.Format("https://login.weixin.qq.com/qrcode/{0}", uuid);
            Image img = client.HttpClientInfo.GetImage(qrcodeUrl);
            return img;
         }
       
        /// <summary>
        /// 主要用于提醒手机端，同步状态
        /// </summary>
        public static void StatusNotifyRequest(this Client client)
        {

            //反馈服务器
            string webwxstatusnotifyUrl = client.Host + "/cgi-bin/mmwebwx-bin/webwxstatusnotify";
            StatusNotifyRequest statusNotifyRequest = new StatusNotifyRequest();
            statusNotifyRequest.BaseRequest = client.baseRequest;
            statusNotifyRequest.Code = 3;
            statusNotifyRequest.FromUserName = client.user.UserName;
            statusNotifyRequest.ToUserName = client.user.UserName;
            statusNotifyRequest.ClientMsgId = OtherUtils.GetJavaTimeStamp();
            //反馈结果可以不理
            client.HttpClientInfo.PostJson<StatusNotifyResponse>(webwxstatusnotifyUrl, statusNotifyRequest);

        }
        /// <summary>
        /// 批量拉去联系人信息
        /// </summary>
        /// <param name="client"></param>
        /// <param name="batchGetContactRequest"></param>
        /// <returns></returns>
        public static BatchGetContactResponse webwxbatchgetcontact(this Client client, BatchGetContactRequest batchGetContactRequest)
        {
            string webwxbatchgetcontactUrl = string.Format(client.Host + "/cgi-bin/mmwebwx-bin/webwxbatchgetcontact?type=ex&r={0}", OtherUtils.GetJavaTimeStamp());
            return client.HttpClientInfo.PostJson<BatchGetContactResponse>(webwxbatchgetcontactUrl, batchGetContactRequest);

        }
        /// <summary>
        /// 获取全部联系人列表
        /// </summary>
        /// <param name="client"></param>
        /// <param name="seq"></param>
        /// <param name="skey"></param>
        /// <returns></returns>
        public static GetContactResponse WebwxgetcontactHttp(this Client client, int seq, string skey)
        {
            string getContactUrl = string.Format(client.Host + "/cgi-bin/mmwebwx-bin/webwxgetcontact?r={0}&seq={1}&skey={2}", OtherUtils.GetJavaTimeStamp(), seq, skey);

            return client.HttpClientInfo.GetStringOnce(getContactUrl).ToObject<GetContactResponse>();

        }

        public static async Task<(string, int, string)> CheckSacnLogin(this Client client, string uuid)
        {
            Dictionary<string, string> param = new Dictionary<string, string>();
            param["loginicon"] = "true";
            param["uuid"] = uuid;
            param["tip"] = "1";
            param["lang"] = "zh_CN";
            param["_"] = OtherUtils.GetTimestamp().ToString();
            param["r"] = (-(int)(DateTime.Now.Ticks / 10000000) / 1579).ToString();
            string result = client.HttpClientInfo.GetString(checkloginLink, param);
            Match match = Regex.Match(result, checkloginCode);
            if (match.Groups[1].Value != "200")
            {
                return ("", match.Groups[1].Value.ToInt(), result);
            }
            Match match2 = Regex.Match(result, checkloginUrl);
            return (match2.Groups[1].Value, 200, result);
        }
        public static async Task<string> LoginSuccess(this Client client, string url, string uuid)
        {

            Dictionary<string, string> param = new Dictionary<string, string>();
            param["loginicon"] = "true";
            param["uuid"] = uuid;
            param["fun"] = "new"; ;
            param["redirect_uri"] = OtherUtils.UrlEncode("https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage");
            string result = client.HttpClientInfo.GetString(url, param);
            return result;
        }

        public static async Task<(bool, string)> AutoLoginHttp(this Client client, string host, string lastCookie)
        {
            try
            {
                if (string.IsNullOrEmpty(lastCookie)) return (false, "");

                string url = host + autoUrl;
                client.HttpClientInfo.CookieContainer.SetCookies(new Uri(url), lastCookie.Replace(";", ","));
                string uin = client.HttpClientInfo.CookieContainer.GetCookies(new Uri(url))["wxuin"].Value;
                if (string.IsNullOrEmpty(uin)) return (false, "");

                string result = client.HttpClientInfo.GetString(url + uin);
                JObject o = (JObject)JsonConvert.DeserializeObject(result);
                if (o["ret"].ToString() != "0") return (false, "");
                string uuid = o["uuid"].ToString();

                return (true, uuid);
            }
            catch { return (false, ""); }
        }

        public static InitResponse init(this HttpClient client, string host, string passTicket, string Skey, long Uin, string DeviceID, string Sid)
        {
            string webwxinitUrl = $"{host}{initLink}?r={OtherUtils.Get_r()}&pass_ticket={passTicket}&skey={Skey}";
            JObject postjson = JObject.FromObject(new
            {
                BaseRequest = new
                {
                    Uin = Uin,
                    Sid = Sid,
                    Skey = Skey,
                    DeviceID = DeviceID
                }
            });
            return client.PostJson<InitResponse>(webwxinitUrl, postjson);
        }
        /// <summary>
        /// 同步登出客户端
        /// </summary>
        /// <returns>可以不用理会结果</returns>
        public static string Logout(this HttpClient client, string host, string sid, long uin, string skey)
        {
            string logoutUrl = $"{host}{logoutlink}?redirect=1&type=0&skey={skey}";
            string body = string.Format("sid={0}&uin={1}", sid, uin);
            string result = string.Empty;
            result = client.PostFormString(logoutUrl, body);
            return result;
        }
        /// <summary>
        /// 同步修改备注
        /// 注意：多次调用该接口会被封
        /// </summary>
        /// <param name="remarkName">需要修改的备注名</param>
        /// <param name="userName">需要修改的联系人UserName</param>
        /// <returns></returns>
        public static SimpleResponse RemarkName(this Client client, string host, string remarkName, string userName)
        {
            return client.OpLog(remarkName, userName, CmdIdType.MODREMARKNAME);
        }
        /// <summary>
        /// 同步顶置聊天
        /// 注意：多次调用该接口会被封
        /// </summary>
        /// <param name="remarkName">备注名，官方接口同时附带这个参数，我们也带上吧</param>
        /// <param name="userName">需要修改的联系人UserName</param>
        /// <returns></returns>
        public static SimpleResponse TopContact(this Client client, string host, string remarkName, string userName)
        {
            return client.OpLog(remarkName, userName, CmdIdType.TOPCONTACT, 1);
        }

        /// <summary>
        /// 同步取消顶置消息
        /// </summary>
        /// <param name="remarkName">备注名，官方接口同时附带这个参数，我们也带上吧</param>
        /// <param name="userName">需要修改的联系人UserName</param>
        /// <returns></returns>
        public static SimpleResponse UnTopContact(this Client client, string remarkName, string userName)
        {
            return client.OpLog(remarkName, userName, CmdIdType.TOPCONTACT, 0);
        }
        /// <summary>
        /// 修改联系人备注
        /// </summary>
        /// <param name="client"></param>
        /// <param name="remarkName"></param>
        /// <param name="userName"></param>
        /// <param name="cmdIdType"></param>
        /// <param name="op"></param>
        /// <returns></returns>
        private static SimpleResponse OpLog(this Client client, string remarkName, string userName, CmdIdType cmdIdType, int op = -1)
        {
            string opLogUrl = client.Host + "/cgi-bin/mmwebwx-bin/webwxoplog";
            if (op != -1)
            {
                TopOpLogRequest request = new TopOpLogRequest()
                {
                    BaseRequest = client.baseRequest,
                    CmdId = cmdIdType,
                    OP = op,
                    RemarkName = remarkName,
                    UserName = userName
                };
                return client.HttpClientInfo.PostJson<SimpleResponse>(opLogUrl, request);
            }
            else
            {
                OpLogRequest request = new OpLogRequest()
                {
                    BaseRequest = client.baseRequest,
                    CmdId = cmdIdType,
                    RemarkName = remarkName,
                    UserName = userName
                };
                return client.HttpClientInfo.PostJson<SimpleResponse>(opLogUrl, request);
            }
        }

        /// <summary>
        /// 群里移除用户，用IsOwner判断自己是不是群主，否则没有权限
        /// </summary>
        /// <param name="roomName"></param>
        /// <param name="delName">用户UserName，英文,分割</param>
        /// <returns></returns>
        public static UpdateChatRoomResponse RemoveChatRoomMember(this Client client, string roomName, List<string> delNameList)
        {
            string delName = string.Join(",", delNameList);
            string url = client.Host + "/cgi-bin/mmwebwx-bin/webwxupdatechatroom?fun=delmember&lang=zh_CN";
            DelMemberChatRoomRequest request = new DelMemberChatRoomRequest()
            {
                BaseRequest = client.baseRequest,
                ChatRoomName = roomName,
                DelMemberList = delName
            };
            return client.HttpClientInfo.PostJson<UpdateChatRoomResponse>(url, request);
        }

        /// <summary>
        /// 添加用户到群聊
        /// </summary>
        /// <param name="roomName">群UserName</param>
        /// <param name="addName">用户UserName，英文,分割</param>
        /// <returns></returns>
        public static UpdateChatRoomResponse AddChatRoomMember(this Client client, string roomName, List<string> addNameList)
        {
            string addName = string.Join(",", addNameList);
            string url = client.Host + "/cgi-bin/mmwebwx-bin/webwxupdatechatroom?fun=addmember&lang=zh_CN";
            AddMemberChatRoomRequest request = new AddMemberChatRoomRequest()
            {
                BaseRequest = client.baseRequest,
                ChatRoomName = roomName,
                AddMemberList = addName
            };
            return client.HttpClientInfo.PostJson<UpdateChatRoomResponse>(url, request);
        }

        /// <summary>
        /// 创建群，调用完成，可以用返回的信息，通过GetBatchGetContact去获取群信息
        /// </summary>
        /// <param name="memberList">UserName的list</param>
        /// <returns></returns>
        public static CreateChatRoomResponse CreateChatRoom(this Client client, List<MemberItem> memberList)
        {
            string url = client.Host + "/cgi-bin/mmwebwx-bin/webwxupdatechatroom?fun=addmember&lang=zh_CN";
            CreateChatRoomRequest request = new CreateChatRoomRequest()
            {
                BaseRequest = client.baseRequest,
                MemberList = memberList,
            };
            return client.HttpClientInfo.PostJson<CreateChatRoomResponse>(url, request);
        }
    }
}
